﻿/*
Audica Uploader - application for convenient uploading to various file hostings
Copyright (C) 2011-2012 Makarov Andrey (Winand)

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "uploadworker.h"
//Q_DECLARE_METATYPE(QMap)
//qScriptRegisterSequenceMetaType<QList<QNetworkReply::RawHeaderPair> >(&engine);

UploadWorker::UploadWorker(QString script, QObject* parent) :
    QObject(parent), scriptPlugins(0), scriptPath(script), timerid(0)
{
    engine = new QScriptEngine(this);
    engine->setProcessEventsInterval(100); //do not block events while script's running (update 10 times/sec)
    debugger.attachTo(engine); //script error signaling
}

void UploadWorker::timerEvent(QTimerEvent* /*event*/) {
    killTimer(timerid);
    timerid = 0;
    emit timeout();
}

void UploadWorker::upload(const QString filepath) {
    if(!QFileInfo(filepath).exists()) {
        qDebug() << "UploadWorker::upload()" << "file not found:" << filepath;
        return;
    }
    QFile scriptFile(appPath() + "/data/" + scriptPath);
    if(!scriptFile.exists() ||
       !scriptFile.open(QFile::ReadOnly | QFile::Text)) {
        qDebug() << "UploadWorker::upload()" << "cannot open script file:" << scriptFile.fileName();
        return;
    }
    QString contents = scriptFile.readAll();

    //create main script object
    ScriptCoreClass* scriptcoreobj = new ScriptCoreClass(engine, this);
    connect(scriptcoreobj, SIGNAL(finished(UploadResult*)), this, SLOT(finished_p(UploadResult*)));
    connect(scriptcoreobj, SIGNAL(resetTimeout(int)), this, SLOT(resetTimeout(int)));
    connect(scriptcoreobj, SIGNAL(progress(qint64, qint64)), this, SIGNAL(progress(qint64, qint64)));
    connect(scriptcoreobj, SIGNAL(setStatusText(QString)), this, SIGNAL(setStatusText(QString)));
    scriptcoreobj->setPluginsList(scriptPlugins);
    scriptcoreobj->setFilepath(filepath);
    QScriptValue scriptcoreval = engine->newQObject(scriptcoreobj);
    engine->globalObject().setProperty("script", scriptcoreval);

    resetTimeout(TIME_SCRIPT_EXEC); //wait script evaluation for /TIME_SCRIPT_EXEC/ ms
    /*QScriptValue result =*/ engine->evaluate(contents, scriptFile.fileName());
    if (engine->hasUncaughtException()) {
        //on exception while evaluating
        QScriptValue exception = engine->uncaughtException();
        qDebug() << "Uncaught exception" <<  exception.toString() << ":" << exception.property("lineNumber").toInt32();
    }
}

void UploadWorker::setPluginsList(QMap<QString, scriptplugin> *plugins) {
    scriptPlugins = plugins;
}

QNetworkAccessManager* UploadWorker::getAccessManager() {
    QNetworkAccessManager* ret = 0; //default is null
    QMetaObject::invokeMethod(this->parent(), "getAccessManager", Q_RETURN_ARG(QNetworkAccessManager*, ret));
    return ret;
}

//reset abortion timer
void UploadWorker::resetTimeout(int waittime) {
    if(timerid) killTimer(timerid);
    timerid = startTimer(waittime);
    //qDebug() << "reset." << waittime;
}

void UploadWorker::finished_p(UploadResult* res) {
    ScriptCoreClass* sender = qobject_cast<ScriptCoreClass*>(QObject::sender());
    killTimer(timerid);
    timerid = 0;
    emit finished(sender->filepath(), res);
}
